home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / itrns211.zip / SRC / ICHAR.C < prev    next >
C/C++ Source or Header  |  1991-10-13  |  15KB  |  464 lines

  1. /*
  2.  *========================================================================== 
  3.  * Copyright 1991 Avinash Chopde, All Rights Reserved.
  4.  *
  5.  * Permission to use, copy, modify and distribute this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation, and that the name of Avinash Chopde not be used in
  10.  * advertising or publicity pertaining to distribution of the software
  11.  * without specific, written prior permission.
  12.  * Avinash Chopde makes no representations about the suitability of this
  13.  * software for any purpose.
  14.  * It is provided "as is" without express or implied warranty.
  15.  *
  16.  * AVINASH CHOPDE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  18.  * IN NO EVENT SHALL AVINASH CHOPDE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  19.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  20.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  21.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  *
  24.  * Author:  Avinash Chopde, 1991
  25.  *        C2 Colonial Drive #4, Andover, MA 01810, USA.
  26.  *
  27.  */
  28.  
  29. #include "itrans.h"
  30.  
  31. static char S_RCSID[] = "$Header: e:/itrans/src/rcs/ichar.c 1.4 91/10/13 16:49:34 avinash Exp $";
  32.  
  33. /* =================================================================== */
  34. static int S_get_cus_form(font_t* fptr, /* the font data structure to use */
  35.         letter_t dlet, /* letter searched for */
  36.         comp_unit_t** cus, /* will return a pointer to the cus here */
  37.         comp_unit_t** imp, /* will return implicit char creation ptr */
  38.         int* lastform,
  39.         int* lastlig); /* whether last two cons have a ligature */
  40. static int S_add_cus(pschar_t psfm[], comp_unit_t* pcu, comp_unit_t cu);
  41. /* =================================================================== */
  42. /* Handle a letter (possibly complex) */
  43.  
  44. /******
  45.         (font_t* fptr, the font data structure to use
  46.         letter_t dlet, letter to convert 
  47.         comp_unit_t pcus[], the comp units that make this
  48.                     letter - all u_pschar are valid
  49.                     PostScript codes, or NO_PSCHAR
  50.                     
  51.         int    size_pcus, array size of ecus- number of elements 
  52.         int *ox, int *oy, the orgin of this letter 
  53.         int *width) the width of this complete letter 
  54. ********/
  55. int make_letter(font_t* fptr,
  56.         letter_t dlet,
  57.         comp_unit_t pcus[],
  58.         int    size_pcus,
  59.         int *ox, int *oy,
  60.         int *width)
  61. {
  62.     int num_pcus; /* number of postscript chars that were added to pcus */
  63.     int pcode;
  64.     comp_unit_t*    lcus;  /* comp units that make the form of
  65.                 * the given letter dlet
  66.                 */
  67.     comp_unit_t*    icus;  /* comp units that make the implicit form
  68.                 * of the given letter dlet
  69.                 */
  70.     comp_unit_t*    startcus;
  71.     letter_t    rcons; /* for recursive calls */
  72.     int x1, y1, w, i, j, c1, c2, lastform, nolig, lastlig;
  73.  
  74.     num_pcus = 0;
  75.     *ox = *oy = 0;
  76.     *width = 0;
  77.     x1 = y1  = w = 0;
  78.  
  79. #ifdef DEBUG
  80. fprintf(stderr, "in make_letter\n");
  81. #endif
  82.     if (!S_get_cus_form(fptr, dlet, &lcus, &icus, &lastform, &lastlig)) {
  83.         /* some error, illegal char, incomplete fptr
  84.          * data structure, etc
  85.          */
  86.     return 0; /* 0 elements added */
  87.     }
  88.  
  89.     /* collect all the PS chars in lcus into the output array */
  90.     while (lcus) {
  91.  
  92.         /* get the PS code of this unit */
  93.     pcode = lcus->u_pschar;
  94.  
  95. #ifdef DEBUG
  96. fprintf(stderr, "while lcus in make_letter: pcode is %d\n", pcode);
  97. #endif /*DEBUG*/
  98.     if (pcode == NO_PSCHAR || (pcode >= 0 && pcode <= 255)) {
  99.         /* valid PostScript code */
  100.  
  101.         num_pcus += S_add_cus(fptr->psfm, &pcus[num_pcus], *lcus);
  102.  
  103.         /* update origin and width */
  104.         /* XXX need to track bounding boxes etc */
  105.  
  106.     } else if (pcode == IMPLICIT_PSCHAR && icus) {
  107.         /* Need to use the implicit char description, and have a
  108.          * valid pointer to comp_units that compose the implicit
  109.          * char.
  110.          */
  111.         startcus = icus;
  112.         while (startcus) {
  113.  
  114. #ifdef DEBUG
  115. fprintf(stderr, "while startcus in make_letter: pcode is %d\n", pcus[num_pcus-1].u_pschar);
  116. #endif /*DEBUG*/
  117.  
  118.             /* error check */
  119.             if ( startcus->u_pschar != NO_PSCHAR &&
  120.             (startcus->u_pschar < 0 || startcus->u_pschar > 255)) {
  121.  
  122.             fprintf(stderr, "ERROR: %d illegal pschar in implicit comp units\n", startcus->u_pschar);
  123.             } else {
  124.             num_pcus += S_add_cus(fptr->psfm,&pcus[num_pcus],*startcus);
  125.         }
  126.  
  127.         startcus = startcus->next;
  128.         }
  129.  
  130.  
  131.     } else if (pcode == IMPLICIT_PSCHAR) {
  132.         /* implies that no implicit char defined for this letter, and
  133.          * the letter is complex, and has to be split into
  134.          * simpler parts
  135.          * The way it is done is that every consonant is
  136.          * printed out in HALF_FORM, except the last
  137.          * consonant, which is printed out in its IMPLICIT_FORM.
  138.          ************
  139.          * What to do here is driven by the CONSONANTS_MANY case
  140.          * in S_get_cus_root()
  141.          * Of course, be careful, this could also be CONS..DOUBLE...
  142.          * in case the IFM file contains SAME_AS CCS statements
  143.          * but no implicit char defns...
  144.          */
  145. #ifdef DEBUG
  146. fprintf(stderr, "make_letter: pcode IMPLICIT, no icus, looping for halfforms\n");
  147. #endif /*DEBUG*/
  148.  
  149.         for (i = 0; i < dlet.n; i ++) {
  150.  
  151. #ifdef DEBUG
  152. fprintf(stderr, "make-letter i %d dlet.n %d lastlig %d\n", i, dlet.n, lastlig);
  153. #endif
  154.         /* check if a ligature has been defined for
  155.          * (current char, next char) pair, use it if available
  156.          */
  157.         if (i < (dlet.n-1)) { /* i.e, two more consonants left..*/
  158.  
  159.             c1 = _I_(dlet.cons[i]); c2 = _I_(dlet.cons[i+1]);
  160.             if (i == (dlet.n-1)) j = lastform; /* last chars */
  161.             else j = HALF_FORM; /* still more to come,so use halfform*/
  162.             nolig = ((dlet.nolig[i]) || (lastlig && i == (dlet.n-3)));
  163. #ifdef DEBUG
  164. fprintf(stderr, "makeletter nolig %d\n", nolig);
  165. #endif
  166.             /* if last lig exists, do not use the 
  167.              * secondlast consonant with the thirdlast consonant.
  168.              * -- just display the thirdlast consonant in
  169.              * half form.
  170.              */
  171.             if (!nolig && fptr->ligatures[c1][c2].cus &&
  172.                     fptr->ligatures[c1][c2].cus[IMPLICIT_FORM]) {
  173.                 /* just check for existence of the IMPLICIT_FORM-
  174.                  * if it exists, the half-form will also
  175.                  * exist---other way around is not true!.
  176.                  */
  177. #ifdef DEBUG
  178.             fprintf(stderr, "C1: %d, C2 %d, cus(%d)\n", c1, c2,
  179.                     fptr->ligatures[c1][c2].cus[j]);
  180. #endif /*DEBUG*/
  181.             /* found ligature! */
  182.                 if (i == (dlet.n-2)) j = lastform; /* last chars */
  183.                 else j = HALF_FORM; /* more to come,so use halfform*/
  184.             rcons.n = 2; rcons.v = j;
  185.             rcons.type = CONSONANT_DOUBLE_TYPE;
  186.             rcons.cons[0] = dlet.cons[i];
  187.             rcons.cons[1] = dlet.cons[i+1];
  188.             rcons.nolig[0] = FALSE;
  189.             i++; /* have used up next char too */
  190.             } else {
  191.             /* no ligature defined, draw a half form */
  192.             rcons.n = 1; rcons.v = HALF_FORM;
  193.             rcons.type = CONSONANT_SINGLE_TYPE;
  194.             rcons.cons[0] = dlet.cons[i];
  195.             }
  196.         } else { /* this is the last char */
  197.             rcons.n = 1; rcons.v = lastform;
  198.             rcons.type = CONSONANT_SINGLE_TYPE;
  199.             rcons.cons[0] = dlet.cons[i];
  200.         }
  201.  
  202.         j = make_letter(fptr, rcons, &pcus[num_pcus],
  203.                 size_pcus - num_pcus, &x1, &y1, &w);
  204.         /* recompute origin, width */
  205.         num_pcus += j;
  206.         }
  207.     } else { /* ERROR */
  208.         fprintf(stderr, "ERROR ERROR: %d illegal pschar in Form comp units\n", pcode);
  209.     }
  210.  
  211.  
  212.     lcus = lcus->next;
  213.     } /* while (lcus) */
  214.  
  215. #ifdef DEBUG
  216. fprintf(stderr, "make_letter::created CUS containging %d cus\n", num_pcus);
  217. #endif /*DEBUG*/
  218.  
  219.     /* keep the next pointers in the pcus correct */
  220.     for (i = 0; i < num_pcus; i ++) {
  221.     pcus[i].next = &pcus[i+1];
  222.     }
  223.     if (num_pcus > 0) pcus[num_pcus-1].next = NULL;
  224.  
  225.     return num_pcus;
  226.  
  227. } /* make_letter() */
  228. /* =================================================================== */
  229. static comp_unit_t S_implicit_cu = {IMPLICIT_PSCHAR, 0, 0, 0, NULL};
  230.  
  231. stat